import sys
import os
sys.path.append(os.getcwd()) # 将当前目录加入sys.path

import math
from ui.Ui_calculateWindow import Ui_MainWindow
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt

class calculateWindow(QtWidgets.QMainWindow, Ui_MainWindow):  
        
    # 数据，不能初始化为空列表（n>=2），列表中的数据也不能为整数的0
    # 如果 test_data.iat[i] == forecast_data.iat[i] 也会报“除零”错误
    test_data = [1.5, 1.2]
    forecast_data = [1.2, 1.5]

    # 如果从模型的界面打开calculate界面，train模块中的五个check只能有一个是被选中的
    # 如果从主页面的界面打开calculate界面，默认所有的模块都被选中
    arimaisTrained = False
    lssvmisTrained = False
    rnnisTrained = False
    lstmisTrained = False
    informerisTrained = False

    mfeisChecked = False
    maeisChecked = False
    mapeisChecked = False
    mpeisChecked = False
    mseisChecked = False
    sseisChecked = False
    smseisChecked = False
    rmseisChecked = False
    nmseisChecked = False 
    
    def __init__(self):
        # super().setupUi(Dialog)
        super(calculateWindow, self).__init__()
        self.setupUi(self)

    def show_cal(self):
        # 展示页面
        verticalHeader = []
        if self.arimaisTrained:
            verticalHeader.append('ARIMA')
        if self.lssvmisTrained:
            verticalHeader.append('LS-SVM')
        if self.rnnisTrained:
            verticalHeader.append('RNN')
        if self.lstmisTrained:
            verticalHeader.append('LSTM')
        if self.informerisTrained:
            verticalHeader.append('Informer')

        horizontalHeader = []
        if self.mfeisChecked:
            horizontalHeader.append('MFE')
        if self.maeisChecked:
            horizontalHeader.append('MAE')
        if self.mapeisChecked:
            horizontalHeader.append('MAPE')
        if self.mpeisChecked:
            horizontalHeader.append('MPE')
        if self.mseisChecked:
            horizontalHeader.append('MSE')
        if self.sseisChecked:
            horizontalHeader.append('SSE')
        if self.smseisChecked:
            horizontalHeader.append('SMSE')
        if self.rmseisChecked:
            horizontalHeader.append('RMSE')
        if self.nmseisChecked:
            horizontalHeader.append('NMSE')
    
        self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
        self.tableWidget.setObjectName("tableWidget")
        self.tableWidget.setColumnCount(len(horizontalHeader))
        self.tableWidget.setRowCount(len(verticalHeader))
        self.tableWidget.setHorizontalHeaderLabels(horizontalHeader)
        self.tableWidget.setVerticalHeaderLabels(verticalHeader)

        self.tableWidget.setEditTriggers(QtWidgets.QTableWidget.NoEditTriggers)
        self.tableWidget.setSelectionMode(QtWidgets.QTableWidget.NoSelection) #不能选中

        for i in range(len(horizontalHeader)):
            self.tableWidget.setColumnWidth(i, 80)
        
        self.tableWidget.setGeometry(QtCore.QRect(20, 30, len(horizontalHeader) * 100 + 40, len(verticalHeader) * 60 + 45))

        newItem = QtWidgets.QTableWidgetItem(str(round(self.MFE(), 2)))
        newItem.setTextAlignment(Qt.AlignCenter)
        self.tableWidget.setItem(0, 0, newItem)  

        newItem = QtWidgets.QTableWidgetItem(str(round(self.MAE(), 2)))
        newItem.setTextAlignment(Qt.AlignCenter)
        self.tableWidget.setItem(0, 1, newItem)

        newItem = QtWidgets.QTableWidgetItem(str(round(self.MAPE(), 2)))
        newItem.setTextAlignment(Qt.AlignCenter)
        self.tableWidget.setItem(0, 2, newItem)

        newItem = QtWidgets.QTableWidgetItem(str(round(self.MPE(), 2)))
        newItem.setTextAlignment(Qt.AlignCenter)
        self.tableWidget.setItem(0, 3, newItem)
        
        newItem = QtWidgets.QTableWidgetItem(str(round(self.MSE(), 2)))
        newItem.setTextAlignment(Qt.AlignCenter)
        self.tableWidget.setItem(0, 4, newItem)

        newItem = QtWidgets.QTableWidgetItem(str(round(self.SSE(), 2)))
        newItem.setTextAlignment(Qt.AlignCenter)
        self.tableWidget.setItem(0, 5, newItem)
        
        newItem = QtWidgets.QTableWidgetItem(str(round(self.SMSE(), 2)))
        newItem.setTextAlignment(Qt.AlignCenter)
        self.tableWidget.setItem(0, 6, newItem)

        newItem = QtWidgets.QTableWidgetItem(str(round(self.RMSE(), 2)))
        newItem.setTextAlignment(Qt.AlignCenter)
        self.tableWidget.setItem(0, 7, newItem)

        newItem = QtWidgets.QTableWidgetItem(str(round(self.NMSE(), 2)))
        newItem.setTextAlignment(Qt.AlignCenter)
        self.tableWidget.setItem(0, 8, newItem)

    def MFE(self):
        print(self.test_data)
        print(self.forecast_data)
        n = min(len(self.test_data), len(self.forecast_data))
        res = 0.0
        for i in range(n):
            res = res + self.test_data.iat[i, 0] - self.forecast_data.iat[i]
        return res / n

    def MAE(self):
        n = min(len(self.test_data), len(self.forecast_data))
        res = 0.0
        for i in range(n):
            res = res + abs(self.test_data.iat[i, 0] - self.forecast_data.iat[i])
        return res / n

    def MAPE(self):
        n = min(len(self.test_data), len(self.forecast_data))
        res = 0.0
        for i in range(n):
            res = res + abs((self.test_data.iat[i, 0] - self.forecast_data.iat[i]) / self.test_data.iat[i, 0])
        return res * 100.0 / n

    def MPE(self):
        n = min(len(self.test_data), len(self.forecast_data))
        res = 0.0
        for i in range(n):
            res = res + (self.test_data.iat[i, 0] - self.forecast_data.iat[i]) / self.test_data.iat[i, 0]
        return res * 100.0 / n

    def MSE(self):
        n = min(len(self.test_data), len(self.forecast_data))
        res = 0.0
        for i in range(n):
            res = res + pow(self.test_data.iat[i, 0] - self.forecast_data.iat[i], 2) 
        return res / n

    def SSE(self):
        n = min(len(self.test_data), len(self.forecast_data))
        res = 0.0
        for i in range(n):
            res = res + pow(self.test_data.iat[i, 0] - self.forecast_data.iat[i], 2)
        return res * 1.0

    def SMSE(self):
        n = min(len(self.test_data), len(self.forecast_data))
        res = 0.0
        for i in range(n):
            e_i = self.test_data.iat[i, 0] - self.forecast_data.iat[i]
            res = res + (e_i / abs(e_i)) *  pow(e_i, 2)
        return res / n

    def RMSE(self):
        n = min(len(self.test_data), len(self.forecast_data))
        res = 0.0
        for i in range(n):
            res = res + pow(self.test_data.iat[i, 0] - self.forecast_data.iat[i], 2) 
        return math.sqrt(res / n)

    def NMSE(self):
        n = min(len(self.test_data), len(self.forecast_data))
        res = 0.0
        test_mean = 0.0
        for i in range(n):
            test_mean += self.test_data.iat[i, 0]
            res += pow(self.test_data.iat[i, 0] - self.forecast_data.iat[i], 2) 
        test_mean = test_mean / n #均值
        test_variance = 0.0 #方差
        for i in range(n):
            test_variance += pow(self.test_data.iat[i, 0] - test_mean, 2)
        test_variance /= (n-1)
        return res / (test_variance * n)